import {ElMessage} from "element-plus";

// export function generateRandomNumbers(form) {
//     let {count, targetMean, targetStdDev, maxValue} = form
//     // targetMean,plusNum,minNum,maxValue
//     // const targetMean = 52.08;
//     // const targetStdDev = 10.76;
//     // const count = 41;
//     // const maxValue = 144;
//     let numbers = [];
//     let sum = 0;
//
//     // 生成符合正态分布的随机数
//     for (let i = 0; i < count; i++) {
//         let num;
//         do {
//             num = Math.round(normalRandom(targetMean, targetStdDev));
//         } while (num < 0 || num > maxValue);
//         numbers.push(num);
//         sum += num;
//     }
//
//     // 调整总和以精确匹配目标均值
//     const targetSum = Math.round(targetMean * count);
//     const diff = targetSum - sum;
//     if (diff !== 0) {
//         adjustNumbers(numbers, diff, maxValue);
//     }
//
//     // 打乱顺序
//     return shuffleArray(numbers);
// }
//
// function normalRandom(mean, stdDev) {
//     let u = 0, v = 0;
//     while (u === 0) u = Math.random();
//     while (v === 0) v = Math.random();
//     return mean + stdDev * Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
// }
//
// function adjustNumbers(arr, diff, maxValue) {
//     const step = diff > 0 ? 1 : -1;
//     let remaining = Math.abs(diff);
//
//     while (remaining > 0) {
//         const index = Math.floor(Math.random() * arr.length);
//         if ((step === 1 && arr[index] < maxValue) ||
//             (step === -1 && arr[index] > 0)) {
//             arr[index] += step;
//             remaining--;
//         }
//     }
// }
//
// function shuffleArray(array) {
//     for (let i = array.length - 1; i > 0; i--) {
//         const j = Math.floor(Math.random() * (i + 1));
//         [array[i], array[j]] = [array[j], array[i]];
//     }
//     return array;
// }

// // 生成并输出结果
// const result = generateRandomNumbers();
// console.log(result.join('\n'));

// export function generateRandomNumbers(form) {
//     let {count, targetMean, targetStdDev, maxValue, decimalPlaces = 0} = form
//
//     // const targetMean = 52.08;
//     // const targetStdDev = 10.76;
//     // const count = 41;
//     let numbers = [];
//     let sum = 0;
//
//     // 生成符合正态分布的随机数
//     for (let i = 0; i < count; i++) {
//         let num;
//         do {
//             num = normalRandom(targetMean, targetStdDev);
//             num = parseFloat(num.toFixed(decimalPlaces));
//         } while (num < 0 || (maxValue && num > maxValue));
//         numbers.push(num);
//         sum += num;
//     }
//
//     // 调整总和以精确匹配目标均值
//     const targetSum = parseFloat((targetMean * count).toFixed(decimalPlaces));
//     const diff = parseFloat((targetSum - sum).toFixed(decimalPlaces));
//     if (diff !== 0) {
//         adjustNumbers(numbers, diff, maxValue, decimalPlaces);
//     }
// // .join('\n');
//     // 打乱顺序并格式化为每行一个数字
//     return shuffleArray(numbers)
// }
//
// function normalRandom(mean, stdDev) {
//     let u = 0, v = 0;
//     while(u === 0) u = Math.random();
//     while(v === 0) v = Math.random();
//     return mean + stdDev * Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
// }
//
// function adjustNumbers(arr, diff, maxValue, decimalPlaces) {
//     const step = diff > 0 ? 1 : -1;
//     let remaining = Math.abs(diff);
//     const adjustment = parseFloat(Math.pow(0.1, decimalPlaces).toFixed(decimalPlaces));
//
//     while (remaining > 0) {
//         const index = Math.floor(Math.random() * arr.length);
//         const newValue = parseFloat((arr[index] + step * adjustment).toFixed(decimalPlaces));
//
//         if ((step === 1 && (!maxValue || newValue <= maxValue)) ||
//             (step === -1 && newValue >= 0)) {
//             remaining = parseFloat((remaining - adjustment).toFixed(decimalPlaces));
//             arr[index] = newValue;
//         }
//     }
// }
//
// function shuffleArray(array) {
//     for (let i = array.length - 1; i > 0; i--) {
//         const j = Math.floor(Math.random() * (i + 1));
//         [array[i], array[j]] = [array[j], array[i]];
//     }
//     return array;
// }
export function generateRandomNumbers(form) {
    const { count, targetMean, targetStdDev, maxValue, decimalPlaces = 0 } = form;
    if (count < 1) throw new Error("count must be at least 1");
    if (targetStdDev <= 0) throw new Error("targetStdDev must be positive");

    // 生成三遍候选数组
    const candidates = [];
    for (let i = 0; i < 10000  ; i++) {
        try {
            const candidate = generateCandidate({ ...form }); // 独立生成单组候选
            candidates.push(candidate);
        } catch (e) {
            // 单次生成失败不影响后续尝试
            console.warn(`第${i+1}次生成失败:`, e.message);
        }
    }

    // 过滤出符合标准差要求的候选（允许0.3误差）
    const validCandidates = candidates.filter(c => {
        const stdDev = sampleStdDev(c.numbers);
        return stdDev < targetStdDev + 0.2;
    });

    if (validCandidates.length === 0) {
        ElMessage.error('未找到符合标准差要求的数组')
        return []
        // throw new Error("三次生成均未找到符合标准差要求的数组");
    }

    // 选择综合最优的候选（平均值最接近，标准差最小）
    validCandidates.sort((a, b) => {
        // 计算平均值绝对差（权重0.4）
        const avgDiffA = Math.abs(a.mean - targetMean);
        const avgDiffB = Math.abs(b.mean - targetMean);
        // 计算标准差绝对差（权重0.6，越小越好）
        const stdDiffA = Math.abs(a.stdDev - targetStdDev);
        const stdDiffB = Math.abs(b.stdDev - targetStdDev);
        // 综合得分：平均值差*0.4 + 标准差差*0.6（升序排列）
        return (avgDiffA * 0.4 + stdDiffA * 0.6) - (avgDiffB * 0.4 + stdDiffB * 0.6);
    });

    // 返回最优候选的格式化结果
    return validCandidates[0].numbers.map(n => n.toFixed(decimalPlaces));
}

// 生成单组候选数组（独立逻辑，含内部循环保护）
function generateCandidate(form) {
    const { count, targetMean, targetStdDev, maxValue, decimalPlaces = 0 } = form;
    const factor = Math.pow(10, decimalPlaces);
    const minSumRaw = targetMean * count;
    const minSumScaled = Math.ceil(minSumRaw * factor);
    const targetSum = minSumScaled / factor;
    const targetAvg = targetSum / count;

    let numbers;
    const maxIterations = 50; // 单组候选的最大生成次数
    let iteration = 0;

    do {
        iteration++;
        if (iteration > maxIterations) {
            throw new Error(`单组生成超过${maxIterations}次未达标`);
        }

        numbers = [];
        let sum = 0;

        const roundToDecimal = (num) => Math.round(num * factor) / factor;

        // 生成初始正态分布随机数（标准差为目标的80%）
        for (let i = 0; i < count; i++) {
            let num;
            do {
                num = normalRandom(targetMean, targetStdDev * 0.8);
                num = roundToDecimal(num);
            } while (num < 0 || (maxValue !== undefined && num > maxValue));
            numbers.push(num);
            sum += num;
        }

        // 调整总和至目标值
        const diff = roundToDecimal(targetSum - sum);
        if (diff !== 0) {
            adjustNumbers(numbers, diff, maxValue, decimalPlaces);
        }

        // 降低标准差
        reduceStdDev(numbers, targetStdDev, targetAvg, maxValue, decimalPlaces);

    } while (sampleStdDev(numbers) >= targetStdDev + 1e-9); // 浮点误差容限

    // 计算关键指标（用于后续排序）
    const mean = numbers.reduce((a, b) => a + b, 0) / count;
    const stdDev = sampleStdDev(numbers);

    return { numbers, mean, stdDev };
}

// 以下工具函数与原逻辑一致（略作优化）
function normalRandom(mean, stdDev) {
    let u = 0, v = 0;
    while (u === 0) u = Math.random();
    while (v === 0) v = Math.random();
    return mean + stdDev * Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v);
}

function adjustNumbers(arr, diff, maxValue, decimalPlaces) {
    const step = diff > 0 ? 1 : -1;
    const adjustment = Math.pow(0.1, decimalPlaces);
    const totalSteps = Math.round(Math.abs(diff) / adjustment);

    for (let i = 0; i < totalSteps; i++) {
        let adjusted = false;
        while (!adjusted) {
            const index = Math.floor(Math.random() * arr.length);
            const current = arr[index];
            const newValue = parseFloat((current + step * adjustment).toFixed(decimalPlaces));

            const inRange = (step === 1 && (maxValue === undefined || newValue <= maxValue)) ||
                (step === -1 && newValue >= 0);
            if (inRange) {
                arr[index] = newValue;
                adjusted = true;
            }
        }
    }
}

function sampleStdDev(arr) {
    const n = arr.length;
    if (n < 2) return 0;
    const mean = arr.reduce((a, b) => a + b, 0) / n;
    const squaredDiffs = arr.map(x => Math.pow(x - mean, 2));
    const variance = squaredDiffs.reduce((a, b) => a + b, 0) / (n - 1);
    return Math.sqrt(variance);
}

function reduceStdDev(arr, targetStdDev, mean, maxValue, decimalPlaces) {
    const count = arr.length;
    if (count < 2) return;

    const adjustmentStep = Math.pow(0.1, decimalPlaces);
    let currentStdDev = sampleStdDev(arr);
    const maxSteps = 50; // 单轮调整次数限制

    for (let step = 0; step < maxSteps && currentStdDev >= targetStdDev; step++) {
        const larger = arr
            .map((val, idx) => ({ val, idx }))
            .filter(x => x.val > mean + 1e-9)
            .sort((a, b) => b.val - a.val);
        const smaller = arr
            .map((val, idx) => ({ val, idx }))
            .filter(x => x.val < mean - 1e-9)
            .sort((a, b) => a.val - b.val);

        if (larger.length === 0 || smaller.length === 0) break;

        const large = larger[0];
        const small = smaller[0];

        const maxReduce = large.val - mean;
        const maxIncrease = mean - small.val;
        const adjustAmmount = Math.min(maxReduce, maxIncrease, adjustmentStep);

        if (adjustAmmount <= 1e-9) continue;

        const newLargeVal = large.val - adjustAmmount;
        const newSmallVal = small.val + adjustAmmount;

        const inRangeLarge = (newLargeVal >= 0) && (maxValue === undefined || newLargeVal <= maxValue);
        const inRangeSmall = (newSmallVal >= 0) && (maxValue === undefined || newSmallVal <= maxValue);

        if (inRangeLarge && inRangeSmall) {
            arr[large.idx] = parseFloat(newLargeVal.toFixed(decimalPlaces));
            arr[small.idx] = parseFloat(newSmallVal.toFixed(decimalPlaces));
            currentStdDev = sampleStdDev(arr);
        }
    }
}

function shuffleArray(array) {
    for (let i = array.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [array[i], array[j]] = [array[j], array[i]];
    }
    return array;
}


export function generateRandomCancerTypes(cancers) {
    // Fisher-Yates洗牌算法实现随机排序
    for (let i = cancers.length - 1; i > 0; i--) {
        const j = Math.floor(Math.random() * (i + 1));
        [cancers[i], cancers[j]] = [cancers[j], cancers[i]];
    }

    // 转换为每行一个元素的文本格式
    return cancers
}

export function copyValue(value) {
    try {
        // 创建一个临时的输入框来存储文本
        const input = document.createElement('textarea');
        input.value = value;
        // 将输入框添加到页面，但不显示
        document.body.appendChild(input);
        input.select(); // 选择输入框的内容
        // 执行复制操作
        const isSuccessful = document.execCommand('copy');
        // 清除临时输入框
        document.body.removeChild(input);
        ElMessage({
            message: `复制成功`,
            duration: 2000,
            type: 'success',
        })
    } catch (err) {
    }
}

// 输出结果
// console.log(generateRandomCancerTypes());